package xml;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import models.HibernateDBGestion;
import models.HibernateDocument;
import models.HibernateOccurence;
import models.HibernateTags;
import models.HibernateWord;

public class DirectoryParser {
	private String baseURI;
	private HashMap<Integer, String> stopliste;
	private float tailleDir;
	
	/**
	 * @param directoryPath - the absolute path of working directory
	 */
	public DirectoryParser(String directoryPath){
		this.baseURI = directoryPath;
		this.stopliste = new HashMap<Integer,String>();
		this.tailleDir = 0;
	}
	
	/**
	 * @param stoplistPath - the absolute path of stopList file
	 */
	public void setStopListe(String stoplistPath){
		BufferedReader br=null;
		String line;
		try {
			br = new BufferedReader(new FileReader(stoplistPath));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		try {
			int i=0;
			while ((line = br.readLine()) != null) {
			   stopliste.put(i, line);
			   i++;
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * This is the directory parser.
	 * All the XML document is parse one by one
	 */
	public void parser(){
		File directory = new File(baseURI);
		String[] filenames;
		XMLParser xp;
		FilenameFilter filter = new FilenameFilter() {
	        public boolean accept(File directory, String fileName) {
	            return fileName.endsWith(".xml");
	        }
	    }; 

		if(directory.isDirectory()){
			filenames = directory.list(filter);
			for (int i=0;i<filenames.length;i++){
				HibernateDocument hd = new HibernateDocument();
				hd.setNom(baseURI+"/"+filenames[i]);
				xp = new XMLParser(hd, this.stopliste);
				xp.parserDoc();
				this.tailleDir += xp.getTailleDoc();
			}
		} else {
			System.out.println(baseURI + " is not a directory");
		}
		
	}
	
	/**
	 * This function is used to update TF point
	 */
	public void evaluateTF(){
		HibernateDBGestion manager = new HibernateDBGestion();
		manager.startConnection();
		List tagList = manager.getListSizePositifTag();
		float s = tagList.size();
		Iterator i = tagList.iterator();
		ArrayList<HibernateOccurence> occList = new ArrayList<HibernateOccurence>();
		while(i.hasNext()){
			HibernateTags tag = (HibernateTags)i.next();
			/* Update TF of all Occurences of this tag */
			List l = manager.getListOccByContainer(tag);
			Iterator i1 = l.iterator();
			while(i1.hasNext()){
				HibernateOccurence occ = (HibernateOccurence)i1.next();
				float f = occ.getFreq();
				occ.setTf(f/((float)0.5+s*tag.getTaille()/tailleDir+f));;
				occList.add(occ);
			}
		}
		manager.saveOrUpdateOccList(occList);
		manager.endConnection();
		System.out.println("TF added");
	}
	
	/**
	 * This function is used to update IDF point
	 */
	public void evaluateIDF(){
		HibernateDBGestion manager = new HibernateDBGestion();
		manager.startConnection();
		List tagList = manager.getListSizePositifTag();
		int N = tagList.size();
		List wordList = manager.getAllWord();
		Iterator i = wordList.iterator();
		while(i.hasNext()){
			HibernateWord w =(HibernateWord)i.next();
			List l = manager.getListOccByElement(w);
			float s = l.size();
			Iterator i1 = l.iterator();
			ArrayList<HibernateOccurence> occList = new ArrayList<HibernateOccurence>();
			float result = (float)Math.log(1.0*N/s);
			while(i1.hasNext()){
				HibernateOccurence occ = (HibernateOccurence)i1.next();
				occ.setIdf(result);
				occList.add(occ);
			}
			manager.saveOrUpdateOccList(occList);
		}
		manager.endConnection();
		System.out.println("IDF added");
	}

	/**
	 * The starting point of the indexation
	 */
	public static void main(String[] argv){
		DirectoryParser dp = new DirectoryParser("/home/luong/git/SearchEngine/SearchEngine/Collection/Collection");
		dp.setStopListe("/home/luong/git/SearchEngine/SearchEngine/stopliste.txt");
		dp.parser();
		System.out.println("All documents indexed!");
		dp.evaluateTF();
		dp.evaluateIDF();
	}
}
